#!/usr/bin/python3
# -*- coding:utf-8 -*-
"""
@File: BasicCommonSqlMethod.py
@Author: lijk34925 
@Date: 2024/6/3 15:53
@desc: 请补充本模块功能说明
"""
import re

from qturboframe.lib.utils.variable import Variable
from qturboframe.lib.webdriver import SeleniumError

from BladeFerm.Lib.Common import logger
from BladeFerm.databases import DB_APP


def act_sql_and_check(input_data=None, ui_expect=None):
    """
    执行sql语句（select）并进行断言的用例，支持根据环境切换到各类信创数据库去执行
    :param input_data:
        - sql: 固定语句
    :param ui_expect:
        - more： 最小期望行，大于0进行检查
        - rows: 行数，默认-1不检查，大于0进行检查
        - other：select 返回的
    :return:
    """
    def __can_convert_to_number(obj):
        try:
            float(obj)  # 尝试转换为浮点数
            return True
        except ValueError:
            return False
    blade_variable = Variable()
    env = blade_variable.get_variable('varg_db_type')
    min_row = int(ui_expect.pop('more', -1))
    rows = int(ui_expect.pop('rows', -1))
    sql_text = input_data.get("sql", "select * from dual")
    sql_text = sql_text.upper()
    logger.debug(f"env: {env}, min_row: {min_row}, rows: {rows}, input_data: {input_data}, ui_expect: {ui_expect}")
    result_list = DB_APP.run_one_sql(sql_text)
    if not re.match("select", sql_text, re.I):
        logger.warning("非 select 语句，不进行断言！")
        return True
    if 0 <= min_row <= len(result_list):
        logger.info("测试结果符合期望，不少于 {} 行".format(min_row))
        return True
    elif min_row > len(result_list):
        err = f"sql 结果不满足最小期望行 {min_row}"
        raise SeleniumError(err)
    else:
        if result_list:
            if 0 < rows != len(result_list):
                err = f'sql 结果返回行数不符合期望! 实际行数: {len(result_list)}， 期望行数：{rows}'
                logger.error(err)
                raise SeleniumError(err)
            for index, unit in enumerate(result_list):
                for k, v in ui_expect.items():
                    exp_key = k.upper()
                    real_value = unit[exp_key]
                    check_flag = False
                    if (__can_convert_to_number(real_value)
                            and __can_convert_to_number(v)
                            and abs(float(real_value) - float(v)) < 0.1):
                        check_flag = True
                    elif re.search(v, real_value, re.I):
                        check_flag = True
                    if check_flag:
                        logger.info(f"检查第 {index} 行结果 {real_value} 符合测试期望值 {v}。")
                    else:
                        err = f'sql 的实际结果：{real_value}不符合期望结果：{v}，断言失败！'
                        logger.error(err)
                        raise SeleniumError(err)
        elif len(result_list) == 0 and rows == 0:
            pass_info = f'sql result error! real rows: {len(result_list)}'
            logger.info(pass_info)
        elif len(result_list) == 0 and len(list(ui_expect.keys())) > 0:
            err = f'sql 结果为空，无法进一步断言！'
            logger.error(err)
            raise SeleniumError(err)
        else:
            warn = 'sql 结果未空，期望也为空！不进行断言！'
            logger.warn(warn)


def modify_index_params(input_data=None, ui_expect=None):
    """
    修改指标的发生条件和限定条件
    SELECT  * FROM hsrcce.rcce_dimension_priority; --发生条件
    SELECT  * FROM hsrcce.RCCE_RISK_QUALIFICATION rrq -- 限定条件
    :param input_data:
    :param ui_expect:
    :return:
    """
    risk_id = input_data.get("指标编号")
    limit_condition = input_data.get("限定条件")
    happen_condition = input_data.get("发生条件")
    if len(risk_id) != 10 or len(risk_id) != 14:
        tip = f'指标编号 {risk_id} 不符合要求，请检查！'
        logger.warning(tip)
        raise SeleniumError(tip)
    if limit_condition:
        limit_condition_sql = (f"update hsrcce.RCCE_RISK_QUALIFICATION rrq "
                               f"set rrq.MANUAL_QUALIFICATION_VALUE = '{limit_condition}' "
                               f"where rrq.RISK_ID = '{risk_id}'")
        DB_APP.run_one_sql(limit_condition_sql)
        logger.info(f"修改指标 {risk_id} 的限定条件为 {limit_condition} 成功！")
    if happen_condition:
        happen_condition_sql = (f"update hsrcce.rcce_dimension_priority rdp "
                               f"set rdp.MANUAL_THRESHOLD_VALUE_LIST = '{happen_condition}' "
                               f"where rdp.DIMENSION_ID = '{risk_id}'")
        if len(happen_condition.split('_')) == 3:
            tip = f'{happen_condition}发生条件格式错误，应该取表hsrcce.rcce_dimension_priority的DIMENSION_ID字段的值'
            logger.warning(tip)
            raise SeleniumError(tip)
        DB_APP.run_one_sql(happen_condition_sql)
        logger.info(f"修改指标 {risk_id} 的发生条件为 {happen_condition} 成功！")


def recover_index_params(input_data=None, ui_expect=None):
    """
    恢复指标的发生条件或限定条件
    :param input_data:
    :param ui_expect:
    :return:
    """
    risk_id = input_data.get("指标编号")
    limit_condition = input_data.get("限定条件", "")
    happen_condition = input_data.get("发生条件", "")
    if len(risk_id) == 10 and limit_condition and limit_condition.upper() == 'NULL':
        limit_condition_sql = (f"update hsrcce.RCCE_RISK_QUALIFICATION rrq "
                               f"set rrq.MANUAL_QUALIFICATION_VALUE = '' "
                               f"where rrq.RISK_ID = '{risk_id}'")
        DB_APP.run_one_sql(limit_condition_sql)
        logger.info(f"恢复指标 {risk_id} 的限定条件成功！")
    if len(risk_id) == 14 and happen_condition and happen_condition.upper() == 'NULL':
        happen_condition_sql = (f"update hsrcce.rcce_dimension_priority rdp "
                               f"set rdp.MANUAL_THRESHOLD_VALUE_LIST = '' "
                               f"where rdp.DIMENSION_ID = '{risk_id}'")
        DB_APP.run_one_sql(happen_condition_sql)
        logger.info(f"恢复指标 {risk_id} 的发生条件为成功！")
    if len(risk_id) != 10 or len(risk_id) != 14:
        tip = f'指标编号 {risk_id} 不符合要求，请检查！'
        logger.warning(tip)
        raise SeleniumError(tip)


def modify_index_add_params(input_data=None, ui_expect=None):
    """
    新增维度（前置条件）
        营业部：西安莲湖路一部
        账户组：重点预警账户组
    指标编号：1101020050
    默认维度的等级修改：   （距离到期天数） --- 维度值
        各级预警默认阈值（距离到期天数）：
        一级：20
        二级：15
        三级：10
        四级：5
        五级：0
        限定值：1101020050_1=1,2,3
    :param input_data:
    :param ui_expect:
    :return:
    """